package com.sgq.vue.utils.resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;


import com.baomidou.mybatisplus.annotation.TableField;

import java.util.Date;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.stream.Collectors;

/**
 * @author: 83778
 * @date: 2023-12-29 17:13
 * @desc:
 */
public class FieldsUtil <T1,T2>{
    public List<Field> getFields(Class clazz){
        Field[] fields = clazz.getDeclaredFields();
        List<Field> list = Arrays.stream(fields).filter(field -> {
//            filter  => 获取满足条件的
            //排除属性值为 serialVersionUID 的 id
            boolean flagUID = field.getName().equals("serialVersionUID") ? false : true ;
            boolean flagID = field.getName().equals("id") ? false : true ;
            boolean flagWeatherApiID = field.getName().equals("weatherApiId") ? false : true ;
            //排除属性值为 @TableField exist = false 的
            boolean exist = true ;
            Annotation[] declaredAnnotations = field.getDeclaredAnnotations();
            for (Annotation declaredAnnotation : declaredAnnotations) {
                Class<? extends Annotation> aClass = declaredAnnotation.annotationType();
                if (aClass.equals(TableField.class)){
                    TableField annotation = field.getAnnotation(TableField.class);
                    exist = annotation.exist() == false ? false : true;
                }
            }
            //false标识不需要此字段
            return flagUID && flagID && flagWeatherApiID && exist;
        }).collect(Collectors.toList());
        return list;
    }

    public  List<T2>  setSameFiledValue(T1 source ,T2 target ,String json ,Integer days){

        //用于返回的天气结果集
        List<T2> weathers = new ArrayList<>();
        //用于存储每个field值集合的map
        HashMap<Field, List> fieldListMap = new HashMap<>();
        Class<?> aClass = source.getClass();
        Class<?> bClass = target.getClass();
        //筛选出需要的字段filed
        List<Field> declaredFields =  getFields(aClass);
        for (Field field : declaredFields) {
            field.setAccessible(true);
            try {
                Object o = field.get(source);
                //找到mapping中有映射关系的filed
                if (o != null &&  !"".equals(o)){
                    //拿到filed的名字
                    String name = field.getName();
                    //通过相同的名字获取B的filed
                    Field targetField = bClass.getDeclaredField(name);
                    targetField.setAccessible(true);
                    //使用前先清空数据
                    JsonUtil.valueList.clear();
                    //从json文件中扎到key与weather属性名字相同的key
                    List<Object> tempList = JsonUtil.getValue(json, o.toString() ,days);
                    List<Object> fieldsValueList = new ArrayList<>();
                    //把结果复制到fieldsValueList
                    for (Object v : tempList) {
                        fieldsValueList.add(v);
                    }
                    if (fieldsValueList != null && fieldsValueList.size() != 0){
                        fieldListMap.put(targetField,fieldsValueList);
                    }

                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        //遍历map,拿每个map中list相同索引所在的值作为属性值
        for (int i = 0; i < days; i++) {
            T2 instance = null;
            try {
                instance = (T2)bClass.newInstance();
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            for (Map.Entry<Field, List> entry : fieldListMap.entrySet()) {
                Field key = entry.getKey();
                List  values = entry.getValue();
                System.out.println(key +" ->" +values);
                    if (i >= values.size()){
                        setFiledByClazz(key,instance,values.get(0));
                    }else {
                        setFiledByClazz(key,instance,values.get(i));
                    }

            }
            weathers.add(instance);
        }
        System.out.println("weathers = " + weathers );
        return weathers;
    }

    private void setFiledByClazz(Field field ,T2 target , Object value){
        try {
            Class<?> type = field.getType();
            if (type == Integer.class){
                field.set(target,Integer.valueOf(value.toString()));
             }else if (type ==  Long.class){
                field.set(target,Long.valueOf(value.toString()));
             }else if (type == Date.class){
                 if (value.toString().contains("T")){
                     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                     LocalDateTime localDateTime = LocalDateTime.parse(value.toString(), DateTimeFormatter.ISO_OFFSET_DATE_TIME);
                     DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                     String date = localDateTime.format(formatter);
                     Date parse = sdf.parse(date);
                     field.set(target,parse);
                 }else {
                     field.set(target, DateFormatUtil.parse(value.toString()));
                 }

             }else {
                 field.set(target,value);
             }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }




}
